<?php
/**
 *
 * @author ninetyseven.
 * @date 2023-03-27 22:53
 */

namespace App\Services;

use App\Enum\BalanceLogEnum;
use App\Enum\CardEnum;
use App\Enum\ScheduleEnum;
use App\Enum\CodeEnum;
use App\Enum\DriverEnum;
use App\Enum\TravelEnum;
use App\Enum\UserCardsEnum;
use App\Enum\VillagerEnum;
use App\Enum\WalletsEnum;
use App\Http\Clients\ZccmzjgyxmClient;
use App\Models\BalanceLogModel;
use App\Models\CardsModel;
use App\Models\CmzjScheduleModel;
use App\Models\DriverCartModel;
use App\Models\DriverModel;
use App\Models\UserCardsModel;
use App\Models\UserEnterpriseModel;
use App\Models\VillagerUserModel;
use App\Models\WalletModel;
use App\Services\Tools\HelpService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class DonationService
{
    /**
     * 获取司机信息.
     * @param int $userId
     * @return array
     * @throws \Exception
     */
    public function getDriverInfo(int $userId = 0): array
    {
        if (empty($userId)) {
            $userId = \request()->userId;
        }

        $info = DriverModel::where('id', $userId)->first();
        if(!$info){
            throw new \Exception('司机信息不存在');
        }

        if($info->status == VillagerEnum::ACCOUNT_STATUS_CANCELLATION){
            throw new \Exception('司机账号已注销');
        }

        $info->status = isset($info->status) ? DriverEnum::DRIVER_STATUS[$info->status] : '';

        if (!empty($info->user_id)) {
            $info = VillagerUserModel::query()->where('id', $info->user_id)->first();
        }
        $cart = DriverCartModel::query()->select()->where('driver_id', $info->id)->first();
        if (!$cart) {
            $info['cart_info'] = [];
        } else {
            $info['cart_info'] = $cart->toArray();
        }
        return $info->toArray();
    }
    public function getCardGYCX()
    {
        return self::_getCards(CardEnum::CARD_TYPE_GYCX);
    }
    public function getCardCommute()
    {
        return self::_getCards(CardEnum::CARD_TYPE_ENTERPRISE_COMMUTE_10W);
    }
    public static function getEnterpriseInfo($userId)
    {
        return UserEnterpriseModel::query()->where(['user_id'=>$userId])->first(['id','enterprise_name','contactor','phone','email']);
    }
    /**
     * 获取出行积分的支付明细
     * @param $request
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public function getGycxPaymentList($request): \Illuminate\Contracts\Pagination\LengthAwarePaginator
    {
        return $this->_getBalanceLog(['user_id'=>$request->userId, 'amount_type'=>WalletsEnum::WALLET_MONEY_TYPE_GYCX_AXD ]);
    }

    /**
     * 获取企业通勤积分的支付明细
     * @param $request
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public function getCommutePaymentList($request)
    {
        return $this->_getBalanceLog(['user_id'=>$request->userId, 'amount_type'=>WalletsEnum::WALLET_MONEY_TYPE_COMMUTE_10W ]);
    }

    /**
     * @param $params
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    private function _getBalanceLog($params)
    {
        return BalanceLogModel::query()->where($params)
            ->select(['order_no','change_type','comment','amount','start_address','end_address','start_time','change_type','order_type','created_at'])
            ->orderBy('id')->paginate(HelpService::perPage());
    }

    /**
     * 购买卡
     * @param $userId
     * @param $cardId
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model
     * @throws \Exception
     */
    public function buyCard($userId, $cardId)
    {
        try {

            $card = self::_getCard($cardId);
            $userInfo = self::_getUserInfo($userId);

            $cardNo = HelpService::createRandNum($card->code);
            $memo = sprintf(CardEnum::CMZJ_BUY_CONTENT, $card->name);

            // 2. 将数据写入user cards表
            $userCard = $this->_insertUserCard($userId, TravelEnum::PLATFORM_DONATION, $card, $cardNo, $memo);

            // 2.1 将扣款写入异步处理
            return $this->_asyncDeductPoint($userCard, $userInfo->phone);
        } catch (\Exception $e){
            throw new \Exception('购买失败：'.$e->getMessage());
        }
    }
    private static function _getUserInfo($userId){
        $userInfo = VillagerUserModel::query()->find($userId);
        if( empty($userInfo) ){
            throw new \Exception('用户不存在！');
        }
        if( empty($userInfo->phone) ){
            throw new \Exception('用户手机号不存在！');
        }
        return $userInfo;
    }
    private static function _getCard($cardId){
        $card = CardsModel::query()->find($cardId);
        if( empty($card) ){
            throw new \Exception('此产品不存在！');
        }

        return $card;
    }
    private function _asyncDeductPoint($userCard, $phone)
    {
        $data = [
            'refer_type'    => $userCard->card_type,
            'refer_no'      => $userCard->card_no,
            'refer_id'      => $userCard->id,
            'status'        => ScheduleEnum::SCHEDULE_STATUS_TODO,
            'user_id'       => $userCard->user_id,
            'user_type'     => $userCard->user_type,
            'phone'         => $phone,
            'amount'        => $userCard->point,
            'pay_unit'      => $userCard->pay_unit,
            'memo'          => $userCard->memo
        ];
        $res = CmzjScheduleModel::query()->create($data);
        if( empty($res) ){
            throw new \Exception('写入扣款进程失败。');
        }
        return $res;
    }

    /**
     * 写balance_log
     * @param $userCard
     * @return bool
     */
    public static function _addAmountLogPayForCard($userCard)
    {
        $logData = [
            'order_no' => $userCard->card_no,
            'order_type'    => BalanceLogEnum::ORDER_TYPE_CARD,
            'user_id' => $userCard->user_id,
            'user_type' => $userCard->user_type,
            'amount' => $userCard->point,
            'amount_type'=> WalletsEnum::WALLET_MONEY_TYPE_POINT,
            'change_type' => WalletsEnum::WALLET_LOG_TYPE_OUT,
            'comment' => $userCard->memo
        ];

        return CommonService::recordAmountLog($logData);
    }

    /**
     * 将数据写入user cards表
     * @param $userId
     * @param $platformId
     * @param $card
     * @param $cardNo
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model
     * @throws \Exception
     */
    private function _insertUserCard($userId, $platformId, $card, $cardNo,$memo)
    {
        $userCard = UserCardsModel::query()->create([
            'card_no'   => $cardNo,
            'user_id'   => $userId,
            'user_type' => $platformId,
            'card_id'   => $card['id'],
            'card_type' => $card['type'],
            'point'     => $card['point'],
            'pay_unit'  => $card['pay_unit'],
            'value_sxcx'  => $card['value_sxcx'],
            'unit'      => $card->getRawOriginal('unit'),
            'memo'      => $memo,
            'pay_status'    => UserCardsEnum::PAY_STATUS_UNPAY,
            'value_dispatch_status' => UserCardsEnum::VALUE_DISPATCH_STATUS_TODO
        ]);
        if( empty($userCard) ){
            throw new \Exception('写入购买失败！');
        }
        return $userCard;
    }

    /**
     * 根据类型返回卡列表
     *
     * @param $type
     * @return array
     */
    private static function _getCards($type): array
    {
        $result = CardsModel::query()->where(['status' => CardEnum::STATUS_ENABLED, 'type' => $type])->orderBy('point')->get(['id', 'name', 'point', 'pay_unit','value_sxcx', 'msg', 'unit']);
        if( !empty($result) ){
            $result = $result->toArray();
            foreach ($result as $key=>$row)
                $result[$key]['pay_unit_name'] = CardEnum::CARD_PAY_UNIT[$row['pay_unit']];
        }else $result = [];
        return $result;
    }
}
